package com.tuzhi.base.web.filter;

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tuzhi.base.web.config.SecurityConfig;
import com.tuzhi.base.web.httpclient.AuthApi;
import com.tuzhi.base.web.interceptor.RSAConfig;
import com.tuzhi.base.web.util.ServletUtil;
import com.tuzhi.common.constants.ResultConstant;
import com.tuzhi.common.constants.security.AuthConstant;
import com.tuzhi.common.domain.LoginUserBO;
import com.tuzhi.common.domain.ResultBO;
import com.tuzhi.common.helper.ResultHelper;
import com.tuzhi.util.RSAUtil;
import com.tuzhi.util.UserContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

import static com.tuzhi.common.constants.security.Constants.AUTHORIZE_TOKEN;
import static com.tuzhi.common.constants.security.Constants.USER_INFO;

//@WebFilter(filterName = "TuZhiSecurityFilter", urlPatterns = "/*")
public class TuZhiSecurityFilter implements Filter {
    private static final Logger log = LoggerFactory.getLogger(TuZhiSecurityFilter.class);
    static ObjectMapper MAPPER = new ObjectMapper();

    /*@Value("${security.sign_code}")
    private String signCode;

    @Value("${security.timestampTolerance}")
    private long timestampTolerance;*/
    @Resource
    AuthApi authApi;

    @Resource
    SecurityConfig securityConfig;


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        Long currentTime = System.currentTimeMillis();
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String uri = httpServletRequest.getRequestURI();
        if (securityConfig.isPermitUri4NoAuthUrl(uri)) {
            //拿用户登陆信息直接过
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        //鉴权内部接口调用
        String sign = ServletUtil.getHeader(httpServletRequest, AuthConstant.SIGN_KEY);
        Long timestamp = ServletUtil.getHeader4Long(httpServletRequest, AuthConstant.TIMESTAMP_KEY);
        String data = securityConfig.getSignStr(timestamp);
        boolean result = RSAUtil.verifySignature(data, sign, timestamp, currentTime, securityConfig.getTimestampTolerance(), RSAConfig.PUBLIC_KEY);
        if (result) {
            log.debug("验证签名通过");
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        //这个应该可以取消了
        String userInfo = httpServletRequest.getHeader(USER_INFO);
        if (StringUtils.isNotBlank(userInfo)) {
            LoginUserBO loginUser;//  存储用户信息的实体类
            try {
                userInfo = URLDecoder.decode(userInfo, StandardCharsets.UTF_8.toString());
                loginUser = MAPPER.readValue(userInfo, LoginUserBO.class);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            if (loginUser != null) {
                UserContext.setUserInfo(loginUser);
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
           /* else {
                log.info("没有从userInfo中找到用户信息。");
                ResultBO resultBO = ResultHelper.error("没有获取到用户信息，请登陆授权访问。");
                ServletUtil.renderJson(response, JSON.toJSONString(resultBO));
                return;
            }*/
        }
        String token = httpServletRequest.getHeader(AUTHORIZE_TOKEN);
        if (StringUtils.isNotBlank(token)) {
            //以token拿用户信息
            ResultBO<LoginUserBO> resultBO = authApi.getCurUser(token);
            if (resultBO.isSuccess()) {
                LoginUserBO loginUserBO = resultBO.getData();
//                String loginUser = MAPPER.writeValueAsString(loginUserBO);
//                userInfo = URLEncoder.encode(JSON.toJSONString(loginUserBO), "UTF-8");
                UserContext.setUserInfo(loginUserBO);
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            } else {
                log.debug("非法token!");
                resultBO = ResultHelper.error(ResultConstant.ERR_TOKEN_ERR.getCode(), ResultConstant.ERR_TOKEN_ERR.getMsg());
                ServletUtil.renderJson(response, JSON.toJSONString(resultBO));
                return;
            }
        }

        log.debug("没有获取到用户信息，请登陆授权访问");
        ResultBO resultBO = ResultHelper.error("没有获取到用户信息，请登陆授权访问。");
        ServletUtil.renderJson(response, JSON.toJSONString(resultBO));
    }


    @Override
    public void destroy() {
        log.debug("{} destroy...", this.getClass());
    }
}
